package com.apes.scm.account.tax.model;

import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.DefaultPersistListener;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.Name;
import com.apes.framework.jpa.comment.Comment;
import com.apes.framework.jpa.generator.ApesGenerator;
import com.apes.framework.util.ApesConst;
import com.apes.framework.util.Arith;
import com.apes.framework.util.MapUtil;
import com.apes.scm.account.res.model.Currency;
import com.apes.scm.account.res.repository.CurrencyRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;

import javax.persistence.*;
import java.util.Map;

/**
 * 功能：税别
 *
 * @author xul
 * @create 2018-02-03 15:32
 */
@Getter
@Setter
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Entity
@EntityListeners(DefaultPersistListener.class)
@Table(name = Tax.CONST_TABLE_NAME)
public class Tax extends Model {
    public static final String CONST_TABLE_NAME = "acc_tax";

    @Id
    @Column(name = "id", length = 8)
    @Comment("税别")
    @ApesGenerator(code = CONST_TABLE_NAME, name = "税别")
    private Long id;

    @Column(name = "name", nullable = false, length = 60)
    @Comment("税别名称")
    private String name; //税别名称

    @Column(name = "type_tax_use", nullable = false, length = 60)
    @Comment("税范围")
    private String typeTaxUse; //税范围：（'sal'：销售），（'purchaseOrder'：采购），（'none'：无）

    @Column(name = "price_include", nullable = false)
    @Comment("在价格中包含：使用的商品和发票价格含税")
    private boolean priceInclude = true; //在价格中包含：使用的商品和发票价格含税

    @Column(name = "amt_type", nullable = false, length = 60)
    @Comment("税金计算方式")
    private String amtType; //税金计算方式：（'fixed'：固定值），（'percent'：价格百分比），（'division'：包括价格税的百分比）

    @Name
    @Column(name = "amt", nullable = false, columnDefinition = ApesConst.FIELD_MONEY_16_4)
    @Comment("金额或税率")
    private double amt; //金额或税率

    @Column(name = "valid", nullable = false)
    @Comment("有效标记")
    private boolean valid = true; //有效

    @Column(name = "ORIGIN", length = 20)
    @Comment("外部ID")
    private String origin; //外部ID

    /**
     * 功能：计算税金
     */
    private double computeAmt(double baseAmt, double qty) {
        if (qty == 0) qty = 1.0;
        if (amtType.equals("fixed")) {
            if (baseAmt != 0) {
                //Math.copySign(x, y) 若y<0，返回-1乘以x的绝对值；否则，返回x的绝对值
                return Math.copySign(qty, baseAmt) * amt;
            } else {
                return qty * amt;
            }
        }
        if ((amtType.equals("percent") && !priceInclude) || (amtType.equals("division") && priceInclude)) {
            return baseAmt * amt / 100;
        }
        if (amtType.equals("percent") && priceInclude) {
            return baseAmt - (baseAmt / (1 + amt / 100));
        }
        if (amtType.equals("division") && !priceInclude) {
            return baseAmt / (1 - amt / 100) - baseAmt;
        }
        return 0.0;
    }

    /**
     * 功能：计算税金
     */
    public Map computeAll(PartyRole company, double priceUnit, double qty) {
        return computeAll(company, null, priceUnit, qty);
    }

    /**
     * 功能：计算税金
     */
    public Map computeAll(PartyRole company, Currency currency, double priceUnit, double qty) {
        if (currency == null) {
            currency = company.getParty().getCorporate().getCurrency();
            if (currency == null) throw new RuntimeException("请维护当前公司对应的币种，公司编码：" + company.getId());
        }
        int decimalPlaces = currency.queryDecimalPlaces(); //小数点位数
        boolean round_tax = ApesConst.ROUND_TAX;
        boolean round_total = ApesConst.ROUND_TOTAL;
        if (!round_tax) decimalPlaces += 6;
        double baseAmt = Arith.round(priceUnit * qty, decimalPlaces);
        double totalExcluded = baseAmt; //不含税总额
        double totalIncluded = baseAmt; //含税总额
        double taxAmt = computeAmt(baseAmt, qty); //税金

        if (round_tax) {
            taxAmt = currency.round(taxAmt);
        } else {
            taxAmt = Arith.round(taxAmt, decimalPlaces);
        }
        if (isPriceInclude()) {
            totalExcluded -= taxAmt;
        } else {
            totalIncluded += taxAmt;
        }

        if (round_total) {
            totalExcluded = currency.round(totalExcluded);
            totalIncluded = currency.round(totalIncluded);
        }
        return MapUtil.mapper("taxAmt", Double.valueOf(taxAmt), //税金
                "totalExcluded", Double.valueOf(totalExcluded),    //不含税金额
                "totalIncluded", Double.valueOf(totalIncluded));  //含税金额
    }

    /**
     * 获取百分比税率
     * @return
     */
    public double obtainPercentTypeTax(){
        if("percent".equals(this.getAmtType())){
            return this.amt / 100 ;
        }else{
            throw new RuntimeException("非价格百分比税率，请检查程序");
        }
    }
}
